
###############################################################################
# Variables used for building
#
# ${PROJECT_NAME}_DEP_ALL_LIB   all packages required to build current project
# ${PROJECT_NAME}_DEP_INTERNAL
# ${PROJECT_NAME}_DEP_EXTERNAL
# ${PROJECT_NAME}_DEP_INCDIR    all include directories to build current project
# ${PROJECT_NAME}_DEP_LIBDIR    all library directories to build current project
# ${PROJECT_NAME}_DEP_LIB       all libraries to be linked
# ${PROJECT_NAME}_SRC           the source files
#
# Variables returned by FIND_PACKAGE()
#
# ${package}_FOUND
# ${package}_INCLUDE_DIRS / ${package}_INCLUDE_DIR
# ${package}_LIBRARY_DIRS
# ${package}_LIBRARIES
#
#==============================================================================
# Variables for building options
# 
# CMAKE_MODULE_PATH
# PROJECT_ALL_DIR               store all directories under the project
#                               used by the find<package>.cmake modules
# PROJECT_ALL_LIB_DIR           store all directories under the project
#                               which stores the built libraries
#
# PROJECT_INCLUDE_PATH
# PROJECT_LIBRARY_PATH
# PROJECT_EXECUTABLE_PATH
#

###############################################################################
# make files under the current directory active

MACRO(SELECT_CURRENT_PROJECT)

    MESSAGE( STATUS
        "--------------------------------------------------------------------" )
    MESSAGE( STATUS "processing: ${PROJECT_NAME}" )

    # save current directory
    SET( PROJECT_ALL_DIR ${PROJECT_ALL_DIR} ${${PROJECT_NAME}_SOURCE_DIR}
        CACHE PATH "" FORCE )

    # clear dependencies
    SET( ${PROJECT_NAME}_DEP_ALL_LIB )
    SET( ${PROJECT_NAME}_DEP_INCDIR )
    SET( ${PROJECT_NAME}_DEP_LIBDIR )
    SET( ${PROJECT_NAME}_DEP_LIB )

    # set source files
    AUX_SOURCE_DIRECTORY( . ${PROJECT_NAME}_SRC )

ENDMACRO(SELECT_CURRENT_PROJECT)

###############################################################################
# process dependencies to the current project

MACRO(ADD_DEPENDENCY DEP_LIB)
    LIST( APPEND ${PROJECT_NAME}_DEP_ALL_LIB ${DEP_LIB} )
ENDMACRO()

MACRO(ADD_INTERNAL_DEPENDENCY DEP_LIB)
    LIST( APPEND ${PROJECT_NAME}_DEP_INTERNAL ${DEP_LIB} )
ENDMACRO()

MACRO(ADD_EXTERNAL_DEPENDENCY DEP_LIB)
    LIST( APPEND ${PROJECT_NAME}_DEP_EXTERNAL ${DEP_LIB} )
ENDMACRO()

MACRO(REMOVE_DEP_DUPLICATES)
    LIST( LENGTH ${PROJECT_NAME}_DEP_INCDIR DEP_INCDIR_LENGTH )
    IF( DEP_INCDIR_LENGTH GREATER 0 )
        LIST( REMOVE_DUPLICATES ${PROJECT_NAME}_DEP_INCDIR )
    ENDIF( DEP_INCDIR_LENGTH GREATER 0 )
    LIST( LENGTH ${PROJECT_NAME}_DEP_LIBDIR DEP_LIBDIR_LENGTH )
    IF( DEP_LIBDIR_LENGTH GREATER 0 )
        LIST( REMOVE_DUPLICATES ${PROJECT_NAME}_DEP_LIBDIR )
    ENDIF( DEP_LIBDIR_LENGTH GREATER 0 )
    LIST( LENGTH ${PROJECT_NAME}_DEP_LIB DEP_LIB_LENGTH )
    IF( DEP_LIB_LENGTH GREATER 0 )
        LIST( REMOVE_DUPLICATES ${PROJECT_NAME}_DEP_LIB )
    ENDIF( DEP_LIB_LENGTH GREATER 0 )
ENDMACRO(REMOVE_DEP_DUPLICATES)

MACRO(ANALYSE_ALL_DEP)
    # analyse the external dependencies
    FOREACH( DEP_LIB ${${PROJECT_NAME}_DEP_EXTERNAL} )
        MESSAGE( STATUS "    analysing external dependency: ${DEP_LIB}" )
        FIND_PACKAGE( ${DEP_LIB} QUIET REQUIRED )
        STRING( TOUPPER ${DEP_LIB} DEP_LIB )
        IF( ${DEP_LIB}_FOUND )
            # include
            LIST(APPEND ${PROJECT_NAME}_DEP_INCDIR ${${DEP_LIB}_INCLUDE_DIRS})
            LIST(APPEND ${PROJECT_NAME}_DEP_INCDIR ${${DEP_LIB}_INCLUDE_DIR})
            # link
            LIST(APPEND ${PROJECT_NAME}_DEP_LIB    ${${DEP_LIB}_LIBRARIES})
        ENDIF( ${DEP_LIB}_FOUND )
    ENDFOREACH( DEP_LIB )
    # analyse the internal dependencies
    FOREACH( DEP_LIB ${${PROJECT_NAME}_DEP_INTERNAL} )
        MESSAGE( STATUS "    analysing internal dependency: ${DEP_LIB}" )
        FIND_PACKAGE( ${DEP_LIB} QUIET REQUIRED )
        STRING( TOUPPER ${DEP_LIB} DEP_LIB )
        IF( ${DEP_LIB}_FOUND )
            # include
            LIST(APPEND ${PROJECT_NAME}_DEP_INCDIR ${${DEP_LIB}_INCLUDE_DIRS})
            # link
            LIST(APPEND ${PROJECT_NAME}_DEP_LIBDIR ${${DEP_LIB}_LIBRARY_DIRS})
            LIST(APPEND ${PROJECT_NAME}_DEP_LIB    ${${DEP_LIB}_LIBRARIES})
        ENDIF( ${DEP_LIB}_FOUND )
    ENDFOREACH( DEP_LIB )
ENDMACRO(ANALYSE_ALL_DEP)

###############################################################################
# setup the build process for library

MACRO(SETUP_LIBRARY_BUILD)

    # analyse deps
    ANALYSE_ALL_DEP()

    # define the build process
    REMOVE_DEP_DUPLICATES()

    MESSAGE( STATUS "    creating building rule: ${PROJECT_NAME}" )
    INCLUDE_DIRECTORIES( ${${PROJECT_NAME}_SOURCE_DIR} )
    INCLUDE_DIRECTORIES( ${${PROJECT_NAME}_DEP_INCDIR} )
    LINK_DIRECTORIES( ${${PROJECT_NAME}_DEP_LIBDIR} )
    ADD_LIBRARY( ${PROJECT_NAME} SHARED ${${PROJECT_NAME}_SRC} )
    LIST( APPEND ${PROJECT_NAME}_LIBRARY ${PROJECT_NAME} )
    TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${${PROJECT_NAME}_DEP_LIB} )

    # save current build directory
    SET( PROJECT_ALL_LIB_DIR ${PROJECT_ALL_LIB_DIR} ${${PROJECT_NAME}_BINARY_DIR}
        CACHE PATH "" FORCE )

    # setup install options

ENDMACRO(SETUP_LIBRARY_BUILD)

###############################################################################
# setup the build process for test programs

MACRO(SETUP_TEST_BUILD)

    # analyse deps
    ANALYSE_ALL_DEP()

    # define the build process
    REMOVE_DEP_DUPLICATES()

    INCLUDE_DIRECTORIES( ${${PROJECT_NAME}_DEP_INCDIR} )
    LINK_DIRECTORIES( ${${PROJECT_NAME}_DEP_LIBDIR} )

    FOREACH( SRC_FILE ${${PROJECT_NAME}_SRC} )
        MESSAGE( STATUS "    creating building rule: ${TAR}" )
        STRING( REPLACE ".cpp" "" TAR ${SRC_FILE} )
        ADD_EXECUTABLE( ${TAR} ${SRC_FILE} )
        TARGET_LINK_LIBRARIES( ${TAR} ${${PROJECT_NAME}_DEP_LIB} )
        LIST( APPEND ${PROJECT_NAME}_EXECUTE ${TAR} )
    ENDFOREACH( SRC_FILE ${${PROJECT_NAME}_SRC} )

    # setup install options

    ## verbose
    ##IF( BUILD_VERBOSE )
        #MESSAGE( STATUS 
            #"----verbose: ${PROJECT_NAME}_DEP_INCDIR: 
            #${${PROJECT_NAME}_DEP_INCDIR}" )
        #MESSAGE( STATUS 
            #"----verbose: ${PROJECT_NAME}_DEP_LIBDIR: 
            #${${PROJECT_NAME}_DEP_LIBDIR}" )
        #MESSAGE( STATUS 
            #"----verbose: ${PROJECT_NAME}_DEP_LIB:
            #${${PROJECT_NAME}_DEP_LIB}" )
    ##ENDIF( BUILD_VERBOSE )

ENDMACRO(SETUP_TEST_BUILD)

###############################################################################
# setup the install process

MACRO(INSTALL_INCLUDE)
    #MESSAGE( "install_headfiles: ${PROJECT_SOURCE_DIR}" )
    #INSTALL( DIRECTORY ${PROJECT_SOURCE_DIR}/
             #DESTINATION ${CMAKE_INSTALL_INCLUDE_DIR}
             #FILES_MATCHING PATTERN "*.h"
                            #PATTERN ".svn" EXCLUDE )
    FILE( GLOB ${PROJECT_NAME}_HEADER_FILES "*.h" )
    INSTALL( FILES ${${PROJECT_NAME}_HEADER_FILES}
             DESTINATION ${CMAKE_INSTALL_INCLUDE_DIR} )
ENDMACRO(INSTALL_INCLUDE)

MACRO(INSTALL_LIBRARY)
    #INSTALL( TARGETS ${PROJECT_NAME}
    INSTALL( TARGETS ${${PROJECT_NAME}_LIBRARY}
             LIBRARY DESTINATION ${CMAKE_INSTALL_LIBRARY_DIR}
             ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBRARY_DIR} )
ENDMACRO(INSTALL_LIBRARY)

MACRO(INSTALL_EXECUTE)
    INSTALL( TARGETS ${${PROJECT_NAME}_EXECUTE}
             RUNTIME DESTINATION ${CMAKE_INSTALL_EXECUTE_DIR} )
ENDMACRO(INSTALL_EXECUTE)

###############################################################################
